数论好题
2721: [Violet 5]樱花
简化版:
求方程 $ \dfrac{1}{X}+\dfrac{1}{Y}= \dfrac{1}{N!}$ 的正整数解的组数,其中 $ N≤10^6 $ 。
解的组数,应模$1e9+7$。
Output:
$1439$
Sample Output:
$102426508$
HINT:
题解:
STEP1:
尝试化简该式子?
可以注意到 $X>N!$
那么可以设 $X = (N!+a)$
代入原式得:
$\dfrac{1}{N!+a}+\dfrac{1}{Y}= \dfrac{1}{N!}$
通分:
$Y×N!+N!\times(N!+a)=Y×(N!+a)$
化简:
$(N!)^2+aN!=aY$
$Y=\dfrac{(N!)^2}{a}+N!$
$a|(N!)^2$ 时$Y$为整数。
任意一个能整除$(N!)^2$的$a$可以确定一个$Y$从而确定$X$也就是该 $ \dfrac{1}{X}+\dfrac{1}{Y}= \dfrac{1}{N!}$方程的一组解。
$∴$ 答案就是$(N!)^2$的约数个数。
STEP2:
但是如何求$(N!)^2$的约数个数?
根据算数基本定理的推论:
$(c1+1)×(c_2+1)×…×(c_m+1)=\prod{i=1}^{m}(c_i+1)$
$c_i$是分解出质因数的指数。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include<cstdio> #define ll long long using namespace std; inline ll read(){ ll ans=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();} while(ch>='0'&&ch<='9'){ans=ans*10+ch-48;ch=getchar();} return ans*f; } void write(ll x){ if(x<0){putchar('-');x=-x;} if(x>9){write(x/10);} putchar(x%10|48); } const int MOD=1e9+7; const int N=1e6; int n; int cnt,prime[N+5]; bool book[N+5]; inline void getprime(){ book[1]=true; for (int i=2;i<=N;i++){ if(!book[i]){ prime[++cnt]=i; } for (int j=1;j<=cnt;j++){ if(i*prime[j]>N){ break; } book[i*prime[j]]=1; if(i%prime[j]==0){ break; } } } } int ct[N+5]; ll ans=1; int main(){ n=read(); getprime(); for (int k=2;k<=n;k++){ int t=k; for (int i=1;i<=cnt && prime[i]*prime[i]<=t;i++){ while(t%prime[i]==0){ ct[prime[i]]++; t/=prime[i]; } } if(t>1){ ct[t]++; } } for (int i=1;i<=cnt;i++){ ct[prime[i]]*=2; ct[prime[i]]%=MOD; ans=(ans*(ct[prime[i]]+1))%MOD; } write(ans); return 0; }
|